/*
 * Copyright 2007. Mount Sinai Hospital, Toronto, Canada.
 * 
 * Licensed under the GNU Lesser General Public License, Version 2. You
 * can find a copy of the license at:
 * 
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 * 
 * IN NO EVENT SHALL MOUNT SINAI HOSPITAL BE LIABLE TO ANY PARTY FOR DIRECT, 
 * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST 
 * PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, 
 * EVEN IF MOUNT SINAI HOSPITAL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
 * DAMAGE.
 * 
 * MOUNT SINAI HOSPITAL SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND 
 * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". 
 * MOUNT SINAI HOSPITAL HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, 
 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 
 */
package com.sinai.mshab.client.ui.basic;

import java.util.Iterator;

import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Widget;
import com.sinai.mshab.client.util.Answer;
import com.sinai.mshab.client.ui.aggregate.DataReceiver;
import com.sinai.mshab.client.ui.aggregate.FormData;

/**
 * A composite containing 4 widgets in one horizontal panel. | Description Label |
 * Text Area | Quantifier label | Error Message | Example: | How often do you
 * blink? |_i_dont_blink__| Times a minute | Error: Please enter a number. |
 * 
 * @author Arthur Kalmenson
 */
public class TextAreaComponent extends QuestionComponent {

	/**
	 * The default height of a TextAreaComponent in pixels.
	 */
	private static final int MSHAB_TEXT_AREA_HEIGHT = 245;

	/**
	 * The default width of a TextAreaComponent in pixels.
	 */
	private static final int MSHAB_TEXT_AREA_WIDTH = 438;

	/**
	 * The height of this TextAreaComponent in pixels.
	 */
	private int height = MSHAB_TEXT_AREA_HEIGHT;

	/**
	 * The width of this TextAreaComponent in pixels.
	 */
	private int width = MSHAB_TEXT_AREA_WIDTH;

	/**
	 * Creates a new TextAreaComponent.
	 * 
	 * @param dbfieldName
	 *            the name of the field to which the textarea information
	 *            corresponds to.
	 * @param tableName
	 *            the name of the database table where the textarea information
	 *            will be stored.
	 * @param description
	 *            The description label that goes before textarea (eg. Name)
	 */
	public TextAreaComponent(String dbfieldName, String tableName,
			String description) {
		initializeWidget(dbfieldName, tableName, description, "", "", true);
	}

	/**
	 * Creates a new TextAreaComponent. The horizontal flag will dictate how the
	 * underlying components will be arranged. If horizontal is true, the
	 * arrangement is as follows:
	 * 
	 * description | widget | quantifier | error_msg
	 * 
	 * If horizontal is false, the arrangement is as follows:
	 * 
	 * description <br />
	 * widget <br />
	 * quantifier <br />
	 * error_msg
	 * 
	 * @param dbfieldName
	 *            the name of the field to which the textarea information
	 *            corresponds to.
	 * @param tableName
	 *            the name of the database table where the textarea information
	 *            will be stored.
	 * @param description
	 *            The description label that goes before textarea (eg. Name)
	 * @param horizontal
	 *            flag to indicate whether horizontal or vertical.
	 */
	public TextAreaComponent(String dbfieldName, String tableName,
			String description, boolean horizontal) {
		initializeWidget(dbfieldName, tableName, description, "", "",
				horizontal);
	}

	/**
	 * Creates a new TextAreaComponent.
	 * 
	 * @param dbfieldName
	 *            the name of the field to which the textarea information
	 *            corresponds to.
	 * @param tableName
	 *            the name of the database table where the textarea information
	 *            will be stored.
	 * @param description
	 *            The description label that goes before textarea (eg. Name)
	 * @param quantifier
	 *            The quantifier label that goes after textarea (eg. /years)
	 */
	public TextAreaComponent(String dbfieldName, String tableName,
			String description, String quantifier) {
		initializeWidget(dbfieldName, tableName, description, quantifier, "",
				true);
	}

	/**
	 * Creates a new TextAreaComponent. The horizontal flag will dictate how the
	 * underlying components will be arranged. If horizontal is true, the
	 * arrangement is as follows:
	 * 
	 * description | widget | quantifier | error_msg
	 * 
	 * If horizontal is false, the arrangement is as follows:
	 * 
	 * description <br />
	 * widget <br />
	 * quantifier <br />
	 * error_msg
	 * 
	 * @param dbfieldName
	 *            the name of the field to which the textarea information
	 *            corresponds to.
	 * @param tableName
	 *            the name of the database table where the textarea information
	 *            will be stored.
	 * @param description
	 *            The description label that goes before textarea (eg. Name)
	 * @param quantifier
	 *            The quantifier label that goes after textarea (eg. /years)
	 * @param horizontal
	 *            flag to indicate whether horizontal or vertical.
	 */
	public TextAreaComponent(String dbfieldName, String tableName,
			String description, String quantifier, boolean horizontal) {
		initializeWidget(dbfieldName, tableName, description, quantifier, "",
				horizontal);
	}

	/**
	 * Creates a new TextAreaComponent.
	 * 
	 * @param dbfieldName
	 *            the name of the field to which the textarea information
	 *            corresponds to.
	 * @param tableName
	 *            the name of the database table where the textarea information
	 *            will be stored.
	 * @param description
	 *            The description label that goes before textarea (eg. Name)
	 * @param quantifier
	 *            The quantifier label that goes after textarea (eg. /years)
	 * @param error_msg
	 *            The error message that gets displayed if the attached
	 *            validators do not pass
	 */
	public TextAreaComponent(String dbfieldName, String tableName,
			String description, String quantifier, String error_msg) {
		initializeWidget(dbfieldName, tableName, description, quantifier,
				error_msg, true);
	}

	/**
	 * Creates a new TextAreaComponent. If horizontal is true, the layout will
	 * be the following:
	 * 
	 * description | widget | quantifier | error
	 * 
	 * If horizontal is false, the layout will be the following:
	 * 
	 * description quantifier error widget
	 * 
	 * @param dbfieldName
	 *            the name of the field to which the text area information
	 *            corresponds to.
	 * @param tableName
	 *            the name of the database table where the text area information
	 *            will be stored.
	 * @param description
	 *            The description label that goes before text area (eg. Name)
	 * @param quantifier
	 *            The quantifier label that goes after text area (eg. /years)
	 * @param error_msg
	 *            The error message that gets displayed if the attached
	 *            validators do not pass
	 * @param horizontal
	 *            the layout of this widget, horizontal or vertical.
	 */
	public TextAreaComponent(String dbfieldName, String tableName,
			String description, String quantifier, String error_msg,
			boolean horizontal) {
		initializeWidget(dbfieldName, tableName, description, quantifier,
				error_msg, horizontal);
	}

	/**
	 * Helper method in creating a new <code>TextComponent</code>. This
	 * allows for us to have one central method for creating a
	 * <code>TextComponent</code> even though we take in a different number of
	 * parameters.
	 * 
	 * @param dbfieldName
	 *            the name of the field to which the textbox information
	 *            corresponds to.
	 * @param tableName
	 *            the name of the database table where the textbox information
	 *            will be stored.
	 * @param description
	 *            The description label that goes before textbox (eg. Name)
	 * @param quantifier
	 *            The quantifier label that goes after textbox (eg. /years)
	 * @param error_msg
	 *            The error message that gets displayed if the attached
	 *            validators do not pass
	 */
	protected void initializeWidget(String dbfieldName, String tableName,
			String description, String quantifier, String error_msg,
			boolean horizontal) {

		// make the new TextArea and give it a normal size.
		TextArea area = new TextArea();
		area.setPixelSize(MSHAB_TEXT_AREA_WIDTH, MSHAB_TEXT_AREA_HEIGHT);
		super.initialize(dbfieldName, tableName, description, quantifier,
				error_msg, area, horizontal);
	}

	/**
	 * Set's the description's label css style.
	 * 
	 * @param style
	 *            the new css style name
	 */
	public void setDescriptionStyleName(String style) {
		this.description_label.setStyleName(style);
	}

	public void sendAnswer(DataReceiver receiver) {
		receiver.sendData(getAnswer());
	}

	public Answer getAnswer() {
		Answer answer = new Answer();
		answer.add(tableName, dbfieldName, ((TextArea) widget).getText());
		answer.add(hiddenFields);
		return answer;
	}

	/**
	 * Populate this widget with FormData using an Answer object
	 * 
	 * @param answer
	 *            the answer object containing the data.
	 */
	public boolean populate(Answer answer) {

		// if answer is null, do nothing
		if (answer == null) {
			return false;
		}

		// walking through all the fields-values of answer
		Iterator field_names = answer.getHashMap().keySet().iterator();
		while (field_names.hasNext()) {
			String field_name = (String) field_names.next();

			// if field name matches our widget's field name, use this value
			if (field_name.equalsIgnoreCase(dbfieldName)) {
				String value = (String) answer.getHashMap().get(field_name);
				((TextArea) widget).setText(value);

				// apply mask if it exists
				if (mask != null) {
					setText(mask.applyMask(getText()));
				}

				// if we populate the widget with nothing, return false.
				if (value == null || value.trim().length() == 0) {
					return false;
				}

				return true;
			}
		}
		return false;
	}

	/**
	 * Populate this widget with FormData
	 */
	public boolean populate() {
		Answer a = FormData.getData(tableName);
		return populate(a);
	}

	/**
	 * Sets this TextArea's width and height to <code>widthPx</code> and
	 * <code>heightPx</code> respectively.
	 * 
	 * @param widthPx
	 *            the width in pixels.
	 * @param heightPx
	 *            the height in pixels.
	 */
	public void setSize(int widthPx, int heightPx) {
		widget.setPixelSize(widthPx, heightPx);
	}

	/**
	 * Returns the height of this TextAreaComponent in pixels.
	 * 
	 * @return the height of this TextAreaComponent in pixels.
	 */
	public int getHeight() {
		return height;
	}

	/**
	 * Returns the width of this TextAreaComponent in pixels.
	 * 
	 * @return the width of this TextAreaComponent in pixels.
	 */
	public int getWidth() {
		return width;
	}

	/**
	 * Sets the text of the textbox to 'message'
	 * 
	 * @param message
	 *            The text that will go to the text field.
	 */
	public void setText(String message) {
		((TextArea) widget).setText(message);
	}

	/**
	 * Returns the text of the textbox.
	 * 
	 * @param message
	 *            The text that is in the textbox
	 */
	public String getText() {
		return ((TextArea) widget).getText();
	}

	public Object clone() {
		BasicFormComponent t;
		t = new TextAreaComponent(dbfieldName, tableName, description,
				quantifier, error_msg);

		t.setMask(this.mask);
		t.setValidator(this.validator);

		if (subquestion)
			t.setAsSubQuestion();

		return t;
	}

	/**
	 * When to focus is lost validate the field.
	 */
	public void onFocus(Widget sender) {
		String name = ((TextArea) widget).getStyleName();
		((TextArea) widget).setStyleName(name + "_focus");
	}

	/**
	 * When to focus is lost validate the field.
	 */
	public void onLostFocus(Widget sender) {

		String name = ((TextArea) widget).getStyleName();
		if (name.indexOf("_focus") != -1) {
			((TextArea) widget).setStyleName(name.substring(0, name.length()
					- "_focus".length()));
		}

		validate();
	}

}
